package utils;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Security;
import java.util.Base64;

public class AesUtil {

    public static String encrypt(String data, String key, String iv) throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        //加密之前，先从Base64格式还原到原始格式
//        Base64.Decoder decoder = Base64.getDecoder();
//        byte[] dataByte = decoder.decode(data);
//        byte[] keyByte = decoder.decode(key);
//        byte[] ivByte = decoder.decode(iv);
        String encryptedData = null;

        //指定算法，模式，填充方式，创建一个Cipher
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");

        //生成Key对象
        Key sKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

        //把向量初始化到算法参数
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)));

        //指定用途，密钥，参数 初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, params);

        //指定加密
        byte[] result = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));

        //对结果进行Base64编码，否则会得到一串乱码，不便于后续操作
        Base64.Encoder encoder = Base64.getEncoder();
        encryptedData = encoder.encodeToString(result);

        return encryptedData;
    }

    public static String decrypt(String encryptedData, String key, String iv) throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        //解密之前先把Base64格式的数据转成原始格式
        Base64.Decoder decoder = Base64.getDecoder();
//        byte[] dataByte = encryptedData.getBytes(StandardCharsets.UTF_8);
//        byte[] keyByte = decoder.decode(key);
//        byte[] ivByte = decoder.decode(iv);

        //指定算法，模式，填充方法 创建一个Cipher实例
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", BouncyCastleProvider.PROVIDER_NAME);

        //生成Key对象
        Key sKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

        //把向量初始化到算法参数
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)));

        //指定用途，密钥，参数 初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec, params);

        //执行解密
        return new String(cipher.doFinal(decoder.decode(encryptedData)));
    }
}
